#!/usr/bin/env python3
"""
完整的API接口测试脚本
测试API_README.md中列出的所有接口
"""

import requests
import json
import time
import subprocess
import threading
import sys
import os
from datetime import datetime

class ComprehensiveAPITester:
    def __init__(self):
        self.base_url = "http://localhost:8000"
        self.admin_token = "admin_secret_token_2024"
        self.server_process = None
        self.test_results = []
        
    def start_server(self):
        """启动服务器"""
        print("🚀 启动服务器...")
        try:
            # 启动服务器进程
            cmd = [sys.executable, "-m", "uvicorn", "backend.main:app", "--host", "0.0.0.0", "--port", "8000"]
            self.server_process = subprocess.Popen(
                cmd,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                cwd=os.getcwd()
            )
            
            # 等待服务器启动
            print("等待服务器启动...")
            time.sleep(8)
            
            # 检查服务器是否响应
            for i in range(10):
                try:
                    response = requests.get(f"{self.base_url}/health", timeout=5)
                    if response.status_code == 200:
                        print("✅ 服务器启动成功")
                        return True
                except:
                    pass
                time.sleep(2)
                print(f"重试 {i+1}/10...")
            
            print("❌ 服务器启动失败")
            return False
            
        except Exception as e:
            print(f"❌ 启动服务器异常: {e}")
            return False
    
    def test_endpoint(self, method, path, headers=None, data=None, description="", expected_status=200):
        """测试单个端点"""
        url = f"{self.base_url}{path}"
        
        try:
            if method.upper() == "GET":
                response = requests.get(url, headers=headers, timeout=10)
            elif method.upper() == "POST":
                response = requests.post(url, headers=headers, json=data, timeout=10)
            elif method.upper() == "PUT":
                response = requests.put(url, headers=headers, json=data, timeout=10)
            elif method.upper() == "DELETE":
                response = requests.delete(url, headers=headers, timeout=10)
            else:
                print(f"❌ 不支持的方法: {method}")
                return False
            
            success = response.status_code == expected_status
            status_icon = "✅" if success else "❌"
            
            print(f"{status_icon} {method} {path} - {description}")
            print(f"   状态码: {response.status_code} (期望: {expected_status})")
            
            if success and response.content:
                try:
                    data = response.json()
                    if isinstance(data, list):
                        print(f"   返回: 列表，{len(data)} 项")
                    elif isinstance(data, dict):
                        print(f"   返回: 对象，{len(data)} 个字段")
                except:
                    print(f"   返回: 非JSON数据")
            elif not success:
                try:
                    error = response.json()
                    print(f"   错误: {error}")
                except:
                    print(f"   错误: {response.text[:100]}")
            
            print()
            
            self.test_results.append({
                "method": method,
                "path": path,
                "description": description,
                "success": success,
                "status_code": response.status_code,
                "expected_status": expected_status
            })
            
            return success
            
        except requests.exceptions.ConnectionError:
            print(f"❌ {method} {path} - {description}")
            print(f"   错误: 连接失败")
            print()
            return False
        except Exception as e:
            print(f"❌ {method} {path} - {description}")
            print(f"   错误: {str(e)}")
            print()
            return False
    
    def run_all_tests(self):
        """运行所有测试"""
        print("🧪 开始完整API测试")
        print("="*60)
        
        admin_headers = {"Authorization": f"Bearer {self.admin_token}"}
        
        # 基础接口测试
        print("📋 基础接口测试")
        print("-" * 30)
        self.test_endpoint("GET", "/health", description="健康检查")
        self.test_endpoint("GET", "/", description="根路径")
        
        # 学生端API测试
        print("🎓 学生端API测试")
        print("-" * 30)
        self.test_endpoint("GET", "/api/questions", description="获取题目列表")
        
        # 提交答案测试
        submit_data = {
            "student_name": "API测试学生",
            "class_id": 1,
            "answers": [{"questionId": 1, "selectedAnswer": "A"}]
        }
        self.test_endpoint("POST", "/api/submit", data=submit_data, description="提交答案")
        
        self.test_endpoint("GET", "/api/scores/1", description="获取班级成绩")
        self.test_endpoint("GET", "/api/class-analysis/1", description="班级分析")
        self.test_endpoint("GET", "/api/student-trajectory/1/API测试学生", description="学生轨迹")
        self.test_endpoint("GET", "/api/error-analysis/1", description="错题分析")
        self.test_endpoint("GET", "/api/teaching-suggestions/1", description="教学建议")
        
        # 新增的学生API
        self.test_endpoint("GET", "/api/student-records?student_name=API测试学生&class_id=1", description="学生记录查询")
        self.test_endpoint("GET", "/api/student-statistics/API测试学生?class_id=1", description="学生统计信息")
        
        # 教师端API测试
        print("👨‍🏫 教师端API测试")
        print("-" * 30)
        self.test_endpoint("GET", "/api/teacher/dashboard?class_id=1", description="教师数据看板")
        self.test_endpoint("GET", "/api/teacher/dashboard/overview?class_id=1", description="数据看板概览")
        self.test_endpoint("GET", "/api/teacher/dashboard/students?class_id=1", description="学生数据")
        self.test_endpoint("GET", "/api/teacher/dashboard/errors?class_id=1", description="错题数据")
        self.test_endpoint("GET", "/api/teacher/dashboard/suggestions?class_id=1", description="教学建议")
        
        # 新增的教师API
        export_data = {"class_id": 1, "format": "excel"}
        self.test_endpoint("POST", "/api/teacher/dashboard/export", data=export_data, description="数据导出")
        
        # 管理员API测试
        print("🔧 管理员API测试")
        print("-" * 30)
        
        # 题目管理
        self.test_endpoint("GET", "/admin/questions", headers=admin_headers, description="获取所有题目")
        
        # 创建题目
        question_data = {
            "questionContent": "API测试题目：什么是RESTful API？",
            "optionA": "表现层状态转换的API设计风格",
            "optionB": "一种数据库查询语言",
            "optionC": "前端框架",
            "optionD": "编程语言",
            "answer": "A",
            "knowledgePoint": "API设计",
            "explanation": "RESTful API是一种基于REST架构风格的API设计方法",
            "questionBankId": 1
        }
        self.test_endpoint("POST", "/admin/questions/create", headers=admin_headers, data=question_data, description="创建题目")
        
        # 题库管理
        self.test_endpoint("GET", "/admin/question-banks", headers=admin_headers, description="获取所有题库")
        self.test_endpoint("GET", "/admin/question-banks/active", headers=admin_headers, description="获取激活题库")
        
        # 创建题库
        bank_data = {
            "name": "API测试题库",
            "description": "用于API测试的题库",
            "created_by": "API测试",
            "is_active": 0
        }
        self.test_endpoint("POST", "/admin/question-banks", headers=admin_headers, data=bank_data, description="创建题库")
        
        # 其他管理员接口
        self.test_endpoint("GET", "/admin/class-config", description="获取班级配置")
        self.test_endpoint("GET", "/admin/llm-configs", headers=admin_headers, description="获取LLM配置")
        
        # 生成测试报告
        self.generate_report()
    
    def generate_report(self):
        """生成测试报告"""
        total_tests = len(self.test_results)
        passed_tests = sum(1 for result in self.test_results if result['success'])
        failed_tests = total_tests - passed_tests
        
        print("📊 API测试报告")
        print("="*60)
        print(f"总测试数: {total_tests}")
        print(f"通过: {passed_tests} ✅")
        print(f"失败: {failed_tests} ❌")
        print(f"成功率: {(passed_tests/total_tests*100):.1f}%")
        print()
        
        if failed_tests > 0:
            print("❌ 失败的测试:")
            for result in self.test_results:
                if not result['success']:
                    print(f"  - {result['method']} {result['path']}: {result['description']} (状态码: {result['status_code']})")
        
        # 保存详细报告
        report_data = {
            "timestamp": datetime.now().isoformat(),
            "summary": {
                "total_tests": total_tests,
                "passed_tests": passed_tests,
                "failed_tests": failed_tests,
                "success_rate": round(passed_tests/total_tests*100, 1)
            },
            "results": self.test_results
        }
        
        with open('comprehensive_api_test_report.json', 'w', encoding='utf-8') as f:
            json.dump(report_data, f, ensure_ascii=False, indent=2)
        
        print(f"\n📄 详细报告已保存到: comprehensive_api_test_report.json")
        
        if passed_tests == total_tests:
            print("\n🎉 所有API接口测试通过！API_README.md文档准确无误！")
        elif passed_tests > total_tests * 0.8:
            print("\n✅ 大部分API接口正常工作，少数接口需要修复")
        else:
            print("\n⚠️  多个API接口存在问题，需要进一步检查和修复")
    
    def cleanup(self):
        """清理资源"""
        if self.server_process:
            print("\n🛑 停止服务器...")
            self.server_process.terminate()
            try:
                self.server_process.wait(timeout=5)
            except subprocess.TimeoutExpired:
                self.server_process.kill()
    
    def run(self):
        """运行完整测试流程"""
        try:
            # 启动服务器
            if not self.start_server():
                print("❌ 无法启动服务器，测试终止")
                return False
            
            # 运行测试
            self.run_all_tests()
            
            return True
            
        except KeyboardInterrupt:
            print("\n⚠️  测试被用户中断")
            return False
        except Exception as e:
            print(f"\n❌ 测试过程中发生异常: {e}")
            return False
        finally:
            self.cleanup()

def main():
    print("🎯 API_README.md 完整性验证测试")
    print("="*60)
    print("本测试将验证API_README.md中列出的所有接口是否正确实现")
    print()
    
    tester = ComprehensiveAPITester()
    success = tester.run()
    
    if success:
        print("\n✅ 测试完成")
    else:
        print("\n❌ 测试失败")

if __name__ == "__main__":
    main()
